package com.itheima.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishDto;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j                                  //日志注解
@RestController                         //控制层响应json注解
@RequestMapping("/dish")                    //路径访问注解
public class DishController {

    //自动按照类型注入菜品服务
    @Autowired
    private DishService dishService;
    //自动按照类型注入口味服务
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    //注入redis缓存服务
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private HttpServletRequest request;

    private int i;

    /**
     * 新增菜品信息
     * @param dish 展示层与服务层之间的数据传输对象
     * @return
     */
    @PostMapping
    public R<String> newDishInformation(@RequestBody DishDto dish) {

        log.info("{}菜品信息录入中...",dish);
        dishService.saveWithFlavor(dish);
        redisTemplate.delete(redisTemplate.keys(dish.getCategoryId()  + "_" + "dish_dto_list"));
        return R.success("Successfully added dishes!!");
    }

    @GetMapping("/page22")        //page=1&pageSize=10&name=xxx
    public R<Page<DishDto>> dishesPagedQuery(@RequestParam(defaultValue = "1") Integer page,
                                    @RequestParam(defaultValue = "10") Integer pageSize,
                                    String name) {

        //创建分页选择器对象
        Page<Dish> dishPage = new Page<>(page, pageSize);

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.like(StringUtils.isNotEmpty(name),Dish::getName,name);

        Page<Dish> dishPageList = dishService.page(dishPage, qw);

        List<Dish> dishList = dishPageList.getRecords();

        String[] cateNames = new String[40];
        for (int i = 0; i < dishList.size(); i++) {

            Dish dish = dishList.get(i);

            QueryWrapper<Category> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(Category::getId,dish.getCategoryId());
            Category category = categoryService.getOne(wrapper);
            cateNames[i] = category.getName();
        }
        Page<DishDto> dtoPage = new Page<>();

        BeanUtils.copyProperties(dishPageList,dtoPage,"records");
        List<Dish> records = dishPage.getRecords();

        List<DishDto> dtoList = records.stream().map((e) -> {

            DishDto dishDto = new DishDto();

            BeanUtils.copyProperties(e, dishDto);

            dishDto.setCategoryName(cateNames[i++]);

            return dishDto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(dtoList);
        return R.success(dtoPage);
    }

    @GetMapping("/page")
    public R<Page<DishDto>> page(int page,int pageSize,String name) {
        Page<Dish> pageInfo = new Page<>(page,pageSize);
        Page<DishDto> dtoPage = new Page<>();

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.eq(null != name,Dish::getName,name);
        dishService.page(pageInfo,qw);

        BeanUtils.copyProperties(pageInfo,dtoPage,"records"); //忽略records字段不注入

        List<Dish> records = pageInfo.getRecords();

        Stream<DishDto> list = records.stream().map((item) -> {
            DishDto dto = new DishDto();
            BeanUtils.copyProperties(item, dto);

            Category cId = categoryService.getById(item.getCategoryId());

            if (cId != null && !"".equals(cId)) {
                dto.setCategoryName(cId.getName());
            }
            return dto;
        });

        dtoPage.setRecords(list.collect(Collectors.toList()));

        return R.success(dtoPage);
    }


    @GetMapping("/{id}")
    public R<DishDto> dishAndFlavorById(@PathVariable Long id) {
        log.info("根据ID查询菜品方法进入了...id:{}",id);

        DishDto idWithFlavor = dishService.getByIdWithFlavor(id);
        System.out.println("idWithFlavor = " + idWithFlavor);
        request.getSession().setAttribute(idWithFlavor.getId() + "_oldCateId",idWithFlavor.getCategoryId());
        return  R.success(idWithFlavor);
    }

    @PutMapping
    public R<String> modifyDishInformation(@RequestBody DishDto dishDto) {

        dishService.updateWithFlavor(dishDto);

        Long resultCateId = (Long) request.getSession().getAttribute(dishDto.getId() + "_oldCateId");
        if (dishDto.getCategoryId() != resultCateId) {
            redisTemplate.delete(redisTemplate.keys(dishDto.getCategoryId() + "_dish_dto_list"));
            redisTemplate.delete(redisTemplate.keys(resultCateId + "_dish_dto_list"));
        } else {
            Set keys = redisTemplate.keys("*_dish_dto_list");   //清理所有分类下的菜品缓存
            redisTemplate.delete(keys);
        }

        return R.success("成功修改进行操作...");
    }


    @GetMapping("/list2")
    public R<List<Dish>> queryTheDishListAccordingToTheCategoryID(Long categoryId) {
        log.info("根据分类ID:{}查询菜品列表",categoryId);

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.eq(categoryId != null && categoryId != 0,Dish::getCategoryId,categoryId);
        //添加条件，查询状态为1（起售状态）的菜品
        qw.eq(Dish::getStatus,1);
        //添加排序条件
        qw.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(qw);
        return R.success(list);
    }

    @GetMapping("/list")
    public R<List<DishDto>> queryDishList(Dish dish) {
        //先从Redis中获取一下分类对应的菜品数据(list集合数据)
        List<DishDto> dishDtoList = redisTemplate.opsForList().range(dish.getCategoryId()  + "_" +"dish_dto_list", 0, -1);
        if (dishDtoList != null && 0 != dishDtoList.size()) return R.success(dishDtoList);
        //如果有数据则直接返回 无需继续下面的代码
        log.info("dish{}",dish);
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.eq(dish.getCategoryId() != null,Dish::getCategoryId,dish.getCategoryId());
        qw.eq(Dish::getStatus,1);
        qw.orderByDesc(Dish::getUpdateTime);
        List<Dish> dishList = dishService.list(qw);

        List<DishDto> dtoList = dishList.stream().map((item) -> {
            DishDto dto = new DishDto();
            BeanUtils.copyProperties(item, dto);

            Long categoryId = dto.getCategoryId();

            Category category = categoryService.getById(categoryId);

            dto.setCategoryName(category.getName());        //设置了菜品分类名称

            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, dto.getId());
            //SQL:select * from dish_flavor where dish_id = ?
            List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
            dto.setFlavors(flavors);
            //将封装的DishDto类集合对象数据存入到redis
            Long push = redisTemplate.opsForList().rightPush(dish.getCategoryId()  + "_" + "dish_dto_list", dto);
            System.out.println("push操作后返回的值:"+push+"-->表示该list类型数据中存储的对象的个数");
            return dto;
        }).collect(Collectors.toList());

        return R.success(dtoList);
    }

    @DeleteMapping
    public R<String> batchDeletion(@RequestParam(required = false) Long[] ids) {

        log.info("需要删除的菜品id:{}",ids);
        dishService.batchDeletion(ids);
        return R.success("成功执行删除操作...");
    }

    /**
     * 批量起售/停售接口
     */
    @PostMapping("/status/{state}")
    public R<String> batchOperation(@PathVariable Integer state ,@RequestParam List<Long> ids) {
        log.info("批量起售、停售操作,参数:状态值[{}]、修改id组[{}]",state,ids);
        dishService.batchOperation(state,ids);
        return R.success("起售/停售操作成功!!");
    }

}
